/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.address;

import com.jnetx.javax.sip.util.ByteArrayUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.text.ParseException;

/**
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
class SipURIParser extends URIParserBase<SipURIImpl> {
    private static final Log logger = LogFactory.getLog(SipURIParser.class);

    protected final Log getLogger() {
        return logger;
    }

    SipURIParser() {
    }

    public SipURIImpl parse(byte[] data, int start, int end, SipURIImpl uriObject) throws ParseException {
        if (uriObject == null) uriObject = new SipURIImpl();
        final int index1 = ByteArrayUtil.firstOccurence(data, ':', start, end);
        if (index1 == -1)
            fail("The URI scheme cannot be recognized!", start);
        final String scheme = new String(data, start, index1 - start);
        if (scheme.equals(""))
            fail("Malformed URI!", start);
        if (scheme.equals("sip"))
            uriObject.setSecure(false);
        else if (scheme.equals("sips"))
            uriObject.setSecure(true);
        else
            fail("Unknown URI scheme: " + scheme, start);
        final int index2 = ByteArrayUtil.firstOccurence(data, '@', index1 + 1, end);
        int hostStart; //where host info starts
        if (index2 != -1) {
            //user info is present
//            final String userInfo = data.substring(index1 + 1, index2);
            if (index2 == index1 + 1)
                fail("User info is malformed!", index1 + 1);
            final int index2_1 = ByteArrayUtil.firstOccurence(data, ':', index1 + 1, index2);
            if (index2_1 != -1) {
                //password is present
                uriObject.setUser(new String(data, index1 + 1, index2_1 - index1 - 1));
                uriObject.setUserPassword(new String(data, index2_1 + 1, index2 - index2_1 -1));
            } else {
                //there is no password in user info
                uriObject.setUser(new String(data, index1 + 1, index2 - index1 -1));
            }
            hostStart = index2 + 1;
        } else {
            hostStart = index1 + 1;
        }
        //Where the URI parameters start
        final int parametersStart = ByteArrayUtil.firstOccurence(data, ';', hostStart, end);
        //Where the URI headers start
        final int headersStart = ByteArrayUtil.firstOccurence(data, '?', parametersStart, end);
        final int hostEnd = parametersStart != -1 ? parametersStart : (headersStart != -1 ? headersStart : end);
        parseHostInfo(data, hostStart, hostEnd, uriObject);
        if (parametersStart != -1)
            //URI contains some parameters, parse them
            parseParameters(data, parametersStart + 1, headersStart != -1 ? headersStart : end, uriObject);
        if (headersStart != -1)
            parseHeaders(data, headersStart + 1, end, uriObject);
        return uriObject;
    }

    private void parseHostInfo(byte[] data, int start, int end, SipURIImpl uriObject) throws ParseException {
        final int index = ByteArrayUtil.firstOccurence(data, ':', start, end);
        if (index != -1) {
            //port is present
            uriObject.setHost(new String(data, start, index - start));
            try {
                uriObject.setPort((int)ByteArrayUtil.parseInteger(data, index + 1, end));
            } catch (Exception e) {
                fail("The URI is malformed: port cannot be parsed!", start + index + 1);
            }
        } else {
            //port is not present
            uriObject.setHost(new String(data, start, end - start));
        }
    }
}
/*
 * $Log$
 */